<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="YmvR2" id="YmvR2"><span data-lake-id="ued9eed41" id="ued9eed41">典型回答</span></h1>
  <p data-lake-id="u44274c0f" id="u44274c0f"><br></p>
  <p data-lake-id="ua4401f56" id="ua4401f56"><span data-lake-id="u66117e83" id="u66117e83">jmap是JDK自带的工具软件，主要用于打印指定Java进程的内存细节。也就是说可以使用jmap生成Heap Dump。</span><strong><span data-lake-id="ub9c19c54" id="ub9c19c54">如果程序内存不足或者频繁GC，很有可能存在内存泄露情况，这时候就要借助Java堆Dump查看对象的情况。</span></strong></p>
  <p data-lake-id="ud749f543" id="ud749f543"><span data-lake-id="u51f058e3" id="u51f058e3">​</span><br></p>
  <blockquote data-lake-id="u5e504f82" id="u5e504f82">
   <p data-lake-id="u10b8105c" id="u10b8105c"><span data-lake-id="u42516dc0" id="u42516dc0">堆Dump是反应Java堆使用情况的内存镜像，其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。 一般，在内存不足、GC异常等情况下，我们就会怀疑有内存泄露。这个时候我们就可以制作堆Dump来查看具体情况。分析原因。</span></p>
  </blockquote>
  <p data-lake-id="u2f44dcb1" id="u2f44dcb1"><br></p>
  <h1 data-lake-id="MFR9d" id="MFR9d"><span data-lake-id="u76426c48" id="u76426c48">扩展知识</span></h1>
  <p data-lake-id="u1706a449" id="u1706a449"><br></p>
  <h2 data-lake-id="DNuHJ" id="DNuHJ"><span data-lake-id="u7947fc24" id="u7947fc24">使用</span></h2>
  <p data-lake-id="ua178cf4f" id="ua178cf4f"><br></p>
  <p data-lake-id="u8ba4cb63" id="u8ba4cb63" style="text-align: justify"><strong><span data-lake-id="u507007b5" id="u507007b5" class="lake-fontsize-12" style="color: rgb(85, 85, 85)">用法摘要</span></strong></p>
  <pre lang="java"><code>
Usage:
    jmap [option] &lt;pid&gt;
        (to connect to running process)
    jmap [option] &lt;executable &lt;core&gt;
        (to connect to a core file)
    jmap [option] [server_id@]&lt;remote server IP or hostname&gt;
        (to connect to remote debug server)

where &lt;option&gt; is one of:
    &lt;none&gt;               to print same info as Solaris pmap
    -heap                to print java heap summary
    -histo[:live]        to print histogram of java object heap; if the "live"
                         suboption is specified, only count live objects
    -permstat            to print permanent generation statistics
    -finalizerinfo       to print information on objects awaiting finalization
    -dump:&lt;dump-options&gt; to dump java heap in hprof binary format
                         dump-options:
                           live         dump only live objects; if not specified,
                                        all objects in the heap are dumped.
                           format=b     binary format
                           file=&lt;file&gt;  dump heap to &lt;file&gt;
                         Example: jmap -dump:live,format=b,file=heap.bin &lt;pid&gt;
    -F                   force. Use with -dump:&lt;dump-options&gt; &lt;pid&gt; or -histo
                         to force a heap dump or histogram when &lt;pid&gt; does not
                         respond. The "live" suboption is not supported
                         in this mode.
    -h | -help           to print this help message
    -J&lt;flag&gt;             to pass &lt;flag&gt; directly to the runtime system
</code></pre>
  <p data-lake-id="ud29af82b" id="ud29af82b"><span data-lake-id="ufea508d8" id="ufea508d8">指定进程号(pid)的进程 jmap [ option ] 指定核心文件 jmap [ option ] 指定远程调试服务器 jmap [ option ] [server-id@]</span></p>
  <p data-lake-id="u1866edbf" id="u1866edbf"><br></p>
  <p data-lake-id="u461666be" id="u461666be"><span data-lake-id="uebfe5945" id="uebfe5945">参数：</span></p>
  <ul list="u9b0b892a">
   <li fid="u8ad15737" data-lake-id="u43293cc6" id="u43293cc6"><span data-lake-id="u3ceaaa1c" id="u3ceaaa1c">option </span></li>
  </ul>
  <ul list="u9b0b892a" data-lake-indent="1">
   <li fid="u8ad15737" data-lake-id="u86a507d3" id="u86a507d3"><span data-lake-id="u09b05145" id="u09b05145">选项参数是互斥的(不可同时使用)。想要使用选项参数，直接跟在命令名称后即可。</span></li>
  </ul>
  <ul list="u9b0b892a" start="2">
   <li fid="u8ad15737" data-lake-id="ud0f1dedd" id="ud0f1dedd"><span data-lake-id="u4238073e" id="u4238073e">pid </span></li>
  </ul>
  <ul list="u9b0b892a" data-lake-indent="1">
   <li fid="u8ad15737" data-lake-id="udbaa7682" id="udbaa7682"><span data-lake-id="ub767a3d5" id="ub767a3d5">需要打印配置信息的进程ID。该进程必须是一个Java进程。想要获取运行的Java进程列表，你可以使用jps。</span></li>
  </ul>
  <ul list="u9b0b892a" start="3">
   <li fid="u8ad15737" data-lake-id="uccf73384" id="uccf73384"><span data-lake-id="uda9eeef3" id="uda9eeef3">executable </span></li>
  </ul>
  <ul list="u9b0b892a" data-lake-indent="1">
   <li fid="u8ad15737" data-lake-id="u0c9a80c2" id="u0c9a80c2"><span data-lake-id="u0ad474ed" id="u0ad474ed">产生核心dump的Java可执行文件。</span></li>
  </ul>
  <ul list="u9b0b892a" start="4">
   <li fid="u8ad15737" data-lake-id="u48a12af7" id="u48a12af7"><span data-lake-id="u4d1a30ac" id="u4d1a30ac">core </span></li>
  </ul>
  <ul list="u9b0b892a" data-lake-indent="1">
   <li fid="u8ad15737" data-lake-id="u105e4f83" id="u105e4f83"><span data-lake-id="u4815b18b" id="u4815b18b">需要打印配置信息的核心文件。</span></li>
  </ul>
  <ul list="u9b0b892a" start="5">
   <li fid="u8ad15737" data-lake-id="u65677d9d" id="u65677d9d"><span data-lake-id="u0ae51fa7" id="u0ae51fa7">remote-hostname-or-IP </span></li>
  </ul>
  <ul list="u9b0b892a" data-lake-indent="1">
   <li fid="u8ad15737" data-lake-id="ue783ed06" id="ue783ed06"><span data-lake-id="ub17a5876" id="ub17a5876">远程调试服务器的(请查看jsadebugd)主机名或IP地址。</span></li>
  </ul>
  <ul list="u9b0b892a" start="6">
   <li fid="u8ad15737" data-lake-id="ua75cb78f" id="ua75cb78f"><span data-lake-id="u8195d884" id="u8195d884">server-id</span></li>
  </ul>
  <ul list="u9b0b892a" data-lake-indent="1">
   <li fid="u8ad15737" data-lake-id="u2971cc3e" id="u2971cc3e"><span data-lake-id="u2c7738f2" id="u2c7738f2">可选的唯一id，如果相同的远程主机上运行了多台调试服务器，用此选项参数标识服务器。</span></li>
  </ul>
  <p data-lake-id="udf1fa7ca" id="udf1fa7ca"><span data-lake-id="u746fae06" id="u746fae06">​</span><br></p>
  <p data-lake-id="u34ac99f3" id="u34ac99f3"><span data-lake-id="u3763da43" id="u3763da43">选项:</span></p>
  <ul list="udd38666b">
   <li fid="u8e592dcd" data-lake-id="u8e73776e" id="u8e73776e"><span data-lake-id="u5765768b" id="u5765768b">&lt;no option&gt;</span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="u8230cbaf" id="u8230cbaf"><span data-lake-id="u7c762c1e" id="u7c762c1e"> 如果使用不带选项参数的jmap打印共享对象映射，将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。这与Solaris的pmap工具比较相似。</span></li>
  </ul>
  <ul list="udd38666b" start="2">
   <li fid="u8e592dcd" data-lake-id="u0e71d2b6" id="u0e71d2b6"><span data-lake-id="u5f5aaf6a" id="u5f5aaf6a">-dump:[live,]format=b,file=&lt;filename&gt;</span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="u47249edf" id="u47249edf"><span data-lake-id="ua5311ad0" id="ua5311ad0"> 以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项，堆中只有活动的对象会被转储。想要浏览heap dump，你可以使用jhat(Java堆分析工具)读取生成的文件。</span></li>
  </ul>
  <ul list="udd38666b" start="3">
   <li fid="u8e592dcd" data-lake-id="u382f4107" id="u382f4107"><span data-lake-id="u0826734c" id="u0826734c">-finalizerinfo </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="uc5c35470" id="uc5c35470"><span data-lake-id="u08e232dd" id="u08e232dd">打印等待终结的对象信息。</span></li>
  </ul>
  <ul list="udd38666b" start="4">
   <li fid="u8e592dcd" data-lake-id="ue19e0ccc" id="ue19e0ccc"><span data-lake-id="u8af1eeaf" id="u8af1eeaf">-heap </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="ua18c3868" id="ua18c3868"><span data-lake-id="u350aca89" id="u350aca89">打印一个堆的摘要信息，包括使用的GC算法、堆配置信息和generation wise heap usage。</span></li>
  </ul>
  <ul list="udd38666b" start="5">
   <li fid="u8e592dcd" data-lake-id="u01401f00" id="u01401f00"><span data-lake-id="ubd37b02f" id="ubd37b02f">-histo[:live] </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="u0ce23609" id="u0ce23609"><span data-lake-id="u9d7841b3" id="u9d7841b3">打印堆的柱状图。其中包括每个Java类、对象数量、内存大小(单位：字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个'*'前缀。如果指定了live子选项，则只计算活动的对象。</span></li>
  </ul>
  <ul list="udd38666b" start="6">
   <li fid="u8e592dcd" data-lake-id="u34798e4a" id="u34798e4a"><span data-lake-id="u34f88cef" id="u34f88cef">-permstat </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="ucd9dc080" id="ucd9dc080"><span data-lake-id="u2be5338c" id="u2be5338c">打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言，它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外，包含的字符串数量和大小也会被打印。</span></li>
  </ul>
  <ul list="udd38666b" start="7">
   <li fid="u8e592dcd" data-lake-id="u688301bf" id="u688301bf"><span data-lake-id="u616689dd" id="u616689dd">-F </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="u9a687cfd" id="u9a687cfd"><span data-lake-id="ud9fbc171" id="ud9fbc171">强制模式。如果指定的pid没有响应，请使用jmap -dump或jmap -histo选项。此模式下，不支持live子选项。</span></li>
  </ul>
  <ul list="udd38666b" start="8">
   <li fid="u8e592dcd" data-lake-id="ufe48f206" id="ufe48f206"><span data-lake-id="ue6d46901" id="ue6d46901">-h </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="u5a4fa50f" id="u5a4fa50f"><span data-lake-id="u94d1c211" id="u94d1c211">打印帮助信息。</span></li>
  </ul>
  <ul list="udd38666b" start="9">
   <li fid="u8e592dcd" data-lake-id="u24f1d4e4" id="u24f1d4e4"><span data-lake-id="ue76f54d6" id="ue76f54d6">-help </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="uebea5f1e" id="uebea5f1e"><span data-lake-id="ud1462b9b" id="ud1462b9b">打印帮助信息。</span></li>
  </ul>
  <ul list="udd38666b" start="10">
   <li fid="u8e592dcd" data-lake-id="ucfe99a3c" id="ucfe99a3c"><span data-lake-id="u999dae6a" id="u999dae6a">-J&lt;flag&gt; </span></li>
  </ul>
  <ul list="udd38666b" data-lake-indent="1">
   <li fid="u8e592dcd" data-lake-id="u9032497c" id="u9032497c"><span data-lake-id="uc0ffd5cb" id="uc0ffd5cb">指定传递给运行jmap的JVM的参数</span></li>
  </ul>
  <p data-lake-id="u9c210f96" id="u9c210f96"><span data-lake-id="uf3bf8ebd" id="uf3bf8ebd">​</span><br></p>
  <h2 data-lake-id="DXrMs" id="DXrMs"><span data-lake-id="u5425fcf9" id="u5425fcf9">典型用法</span></h2>
  <p data-lake-id="u30780406" id="u30780406"><br></p>
  <p data-lake-id="ub9bf7208" id="ub9bf7208"><strong><span data-lake-id="u425d591e" id="u425d591e">查看java 堆（heap）使用情况</span></strong><span data-lake-id="u8928fd6c" id="u8928fd6c">，执行命令： hollis@hos:~/workspace/design_apaas/apaasweb/control/bin$ jmap -heap 31846</span></p>
  <p data-lake-id="u5df80765" id="u5df80765"><span data-lake-id="u5a9d6d71" id="u5a9d6d71">​</span><br></p>
  <pre lang="java"><code>
Attaching to process ID 31846, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.71-b01

using thread-local object allocation.
Parallel GC with 4 thread(s)//GC 方式

Heap Configuration: //堆内存初始化配置
   MinHeapFreeRatio = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
   MaxHeapFreeRatio = 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
   MaxHeapSize      = 2082471936 (1986.0MB) //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
   NewSize          = 1310720 (1.25MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
   MaxNewSize       = 17592186044415 MB//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
   OldSize          = 5439488 (5.1875MB)//对应jvm启动参数-XX:OldSize=&lt;value&gt;:设置JVM堆的‘老生代’的大小
   NewRatio         = 2 //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
   SurvivorRatio    = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值 
   PermSize         = 21757952 (20.75MB)  //对应jvm启动参数-XX:PermSize=&lt;value&gt;:设置JVM堆的‘永生代’的初始大小
   MaxPermSize      = 85983232 (82.0MB)//对应jvm启动参数-XX:MaxPermSize=&lt;value&gt;:设置JVM堆的‘永生代’的最大大小
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage://堆内存使用情况
PS Young Generation
Eden Space://Eden区内存分布
   capacity = 33030144 (31.5MB)//Eden区总容量
   used     = 1524040 (1.4534378051757812MB)  //Eden区已使用
   free     = 31506104 (30.04656219482422MB)  //Eden区剩余容量
   4.614088270399305% used //Eden区使用比率
From Space:  //其中一个Survivor区的内存分布
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
To Space:  //另一个Survivor区的内存分布
   capacity = 5242880 (5.0MB)
   used     = 0 (0.0MB)
   free     = 5242880 (5.0MB)
   0.0% used
PS Old Generation //当前的Old区内存分布
   capacity = 86507520 (82.5MB)
   used     = 0 (0.0MB)
   free     = 86507520 (82.5MB)
   0.0% used
PS Perm Generation//当前的 “永生代” 内存分布
   capacity = 22020096 (21.0MB)
   used     = 2496528 (2.3808746337890625MB)
   free     = 19523568 (18.619125366210938MB)
   11.337498256138392% used

670 interned Strings occupying 43720 bytes.
</code></pre>
  <p data-lake-id="u7691a6c1" id="u7691a6c1"><br></p>
  <p data-lake-id="u67fce8ce" id="u67fce8ce"><br></p>
  <p data-lake-id="u17502e1b" id="u17502e1b"><strong><span data-lake-id="ua172fac4" id="ua172fac4">查看堆内存(histogram)中的对象数量及大小</span></strong><span data-lake-id="u55015d88" id="u55015d88">。执行命令： hollis@hos:~/workspace/design_apaas/apaasweb/control/bin$ jmap -histo 3331</span></p>
  <pre lang="java"><code>
num     #instances         #bytes  class name
编号     个数                字节     类名
----------------------------------------------
   1:             7        1322080  [I
   2:          5603         722368  &lt;methodKlass&gt;
   3:          5603         641944  &lt;constMethodKlass&gt;
   4:         34022         544352  java.lang.Integer
   5:           371         437208  &lt;constantPoolKlass&gt;
   6:           336         270624  &lt;constantPoolCacheKlass&gt;
   7:           371         253816  &lt;instanceKlassKlass&gt;
</code></pre>
  <p data-lake-id="ufb790ed5" id="ufb790ed5"><br></p>
  <p data-lake-id="u8d9d899f" id="u8d9d899f"><span data-lake-id="ua03cdef5" id="ua03cdef5">jmap -histo:live 这个命令执行，JVM会先触发gc，然后再统计信息。</span></p>
  <p data-lake-id="ua687cc62" id="ua687cc62"><span data-lake-id="u0441df14" id="u0441df14">​</span><br></p>
  <p data-lake-id="u7bc5868e" id="u7bc5868e"><strong><span data-lake-id="u7f19fe32" id="u7f19fe32">将内存使用的详细情况输出到文件</span></strong><span data-lake-id="uad6898f6" id="uad6898f6">，执行命令： hollis@hos:~/workspace/design_apaas/apaasweb/control/bin$ jmap -dump:format=b,file=heapDump 6900</span></p>
  <p data-lake-id="uef1c1ce9" id="uef1c1ce9"><span data-lake-id="ucabb6026" id="ucabb6026">​</span><br></p>
  <p data-lake-id="u31869ebd" id="u31869ebd"><span data-lake-id="u9ee06790" id="u9ee06790">然后用</span><span data-lake-id="u2adf44b5" id="u2adf44b5">jhat</span><span data-lake-id="u954ca12c" id="u954ca12c">命令可以参看</span><span data-lake-id="uec0256a4" id="uec0256a4"> </span><span data-lake-id="u99b8996a" id="u99b8996a">jhat -port 5000 heapDump</span><span data-lake-id="u54d8cb79" id="u54d8cb79"> </span><span data-lake-id="u5326ed16" id="u5326ed16">在浏览器中访问：</span><span data-lake-id="u08dcba7c" id="u08dcba7c">http://localhost:5000/</span><span data-lake-id="u33497a87" id="u33497a87"> </span><span data-lake-id="u7b689f55" id="u7b689f55">查看详细信息</span></p>
  <p data-lake-id="u031605d4" id="u031605d4"><br></p>
 </body>
</html>